package com.shop.milk_tea_shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shop.milk_tea_shop.common.CodeEnum;
import com.shop.milk_tea_shop.common.GlobalInfo;
import com.shop.milk_tea_shop.common.PageInfo;
import com.shop.milk_tea_shop.common.Result;
import com.shop.milk_tea_shop.dto.OrderDetailDTO;
import com.shop.milk_tea_shop.dto.OrderItemDTO;
import com.shop.milk_tea_shop.dto.OrderOptions;
import com.shop.milk_tea_shop.entity.*;
import com.shop.milk_tea_shop.mapper.OrderDetailMapper;
import com.shop.milk_tea_shop.mapper.ShopInfoMapper;
import com.shop.milk_tea_shop.request.OrderAddRequest;
import com.shop.milk_tea_shop.request.OrderQueryRequest;
import com.shop.milk_tea_shop.service.ItemAddService;
import com.shop.milk_tea_shop.service.ItemInfoService;
import com.shop.milk_tea_shop.service.OrderDetailService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.milk_tea_shop.utils.ItemUtils;
import com.shop.milk_tea_shop.utils.OrderUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yjw
 * @since 2024-06-16
 */
@Service
public class OrderDetailServiceImpl extends ServiceImpl<OrderDetailMapper, OrderDetail> implements OrderDetailService {

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private ShopInfoMapper shopInfoMapper;

    @Autowired
    private ItemInfoService itemInfoService;

    @Autowired
    private ItemAddService itemAddService;

    @Override
    public OrderDetailDTO order(OrderAddRequest request) {
        LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(OrderDetail::getCreateTime);
        List<OrderDetail> orderDetails = orderDetailMapper.selectList(queryWrapper);
        OrderDetail lastOrderDetail = orderDetails.get(0);

        // 生成新订单的订单号
        String orderId = OrderUtils.getOrderId(lastOrderDetail.getOrderId(), request.getPickup(), request.getShopId());
        String pickupNumber = OrderUtils.getPickupNumber(orderId);
        // 新建订单
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(orderId);
        orderDetail.setShopId(request.getShopId());
        orderDetail.setUserId(request.getUserId());
        orderDetail.setItems(request.getItems());
        orderDetail.setPickupNumber(pickupNumber);
        orderDetail.setTotal(request.getTotal());
        orderDetail.setStatus(1);
        // TODO 积分操作
        orderDetailMapper.insert(orderDetail);
        return orderDetailInfo(orderDetail);
    }

    @Override
    public OrderDetailDTO getOrderById(String orderId) {
        OrderDetail orderDetail = orderDetailMapper.selectById(orderId);
        return orderDetailInfo(orderDetail);
    }

    @Override
    public Result<List<OrderDetailDTO>> paged(OrderQueryRequest request) {
        LambdaQueryWrapper<OrderDetail> queryWrapper  = new LambdaQueryWrapper<>();
        queryWrapper.eq(request.getShopId() != null, OrderDetail::getShopId, request.getShopId());
        queryWrapper.eq(request.getUserId() != null, OrderDetail::getUserId, request.getUserId());
        queryWrapper.eq(request.getStatus() != null, OrderDetail::getStatus, request.getStatus());

        Page<OrderDetail> page = new Page<>(request.getPageNum(), request.getPageSize());
        Page<OrderDetail> pageResult = orderDetailMapper.selectPage(page, queryWrapper);
        PageInfo pageInfo = new PageInfo(pageResult.getCurrent(), pageResult.getSize(), pageResult.getTotal());
        GlobalInfo globalInfo = new GlobalInfo(pageInfo);

        // 解析并补全订单详情信息
        List<OrderDetailDTO> result = new ArrayList<>();
        pageResult.getRecords().forEach(record -> result.add(orderDetailInfo(record)));
        return new Result<>(CodeEnum.SUCCESS.getMsg(), CodeEnum.SUCCESS, result, globalInfo);
    }

    /**
     * 返回刚生成的订单详情信息（包含商品详情的解析）
     * @param orderDetail
     * @return
     */
    private OrderDetailDTO orderDetailInfo(OrderDetail orderDetail) {
        OrderDetailDTO orderDetailDTO = new OrderDetailDTO();
        orderDetailDTO.setOrderId(orderDetail.getOrderId());
        orderDetailDTO.setPickupNumber(orderDetail.getPickupNumber());
        ShopInfo shopInfo = shopInfoMapper.selectById(orderDetail.getShopId());
        orderDetailDTO.setShopInfo(shopInfo);
        orderDetailDTO.setUserId(orderDetail.getUserId());
        // 获取订单中的商品列表信息
        List<OrderItemDTO> orderItemDTOS = getOrderItemDetail(orderDetail.getItems());
        orderDetailDTO.setItems(orderItemDTOS);
        orderDetailDTO.setTotal(orderDetail.getTotal());
        orderDetailDTO.setStatus(orderDetail.getStatus());
        orderDetailDTO.setCreateTime(orderDetail.getCreateTime());
        orderDetailDTO.setExtra(orderDetail.getExtra());
        return orderDetailDTO;
    }

    /**
     * 解析订单中的商品字段，获取得到对应的商品详情信息（含附加信息的解析）
     * @param items
     * @return
     */
    private List<OrderItemDTO> getOrderItemDetail(String items) {
        // 解析string，拿到商品和附加的id
        List<OrderOptions> optionsList = ItemUtils.parseOptions(items);
        List<Long> itemIds = new ArrayList();
        List<Long> options = new ArrayList<>();
        optionsList.forEach(x -> {
            itemIds.add(x.getId());
            options.addAll(x.getOption());
        });

        Map<Long, ItemInfo> itemInfoMap = itemInfoService.listByIds(itemIds)
                .stream()
                .collect(Collectors.toMap(x -> x.getItemId(), x -> x));

        Map<Long, ItemAdd> itemAddMap = itemAddService.listByIds(options)
                .stream()
                .collect(Collectors.toMap(x -> x.getAddId(), x -> x));

        // 逐一补全订单中单个商品的详情信息，包括基本信息和附加信息
        List<OrderItemDTO> orderItemDTOS = new ArrayList<>();
        optionsList.forEach(item -> {
            Long id = item.getId();
            OrderItemDTO orderItemDTO = new OrderItemDTO();
            orderItemDTO.setItemId(id);
            ItemInfo itemInfo = itemInfoMap.get(id);
            orderItemDTO.setItemName(itemInfo.getItemName());
            orderItemDTO.setPrice(itemInfo.getPrice());
            orderItemDTO.setPic(itemInfo.getElements());

            List<Long> option = item.getOption();
            List<String> optionNameList = new ArrayList<>();
            option.forEach(x -> optionNameList.add(itemAddMap.get(x).getAddName()));
            orderItemDTO.setOption(optionNameList);

            orderItemDTOS.add(orderItemDTO);
        });
        return orderItemDTOS;
    }
}
